package edu.hawaii.teams.halealohacli.command;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import org.wattdepot.client.WattDepotClient;
import org.junit.Test;

/**
 * Tests the RankTowers class.
 * 
 * @author Branden Ogata
 * 
 */
public class TestRankTowers {

  /**
   * Tests the getData method in the RankTowers class. Note that any test dates must come after the
   * server reset on 23 November 2011 (technically 22 November 2011, but the first full day of data
   * is 23 November).
   * 
   * @throws Exception Handles any errors that do occur, such as timeouts.
   */
  @Test
  public void testGetData() throws Exception {
    // For connecting to the server and the RankTowers class
    WattDepotClient client = new WattDepotClient("http://server.wattdepot.org:8190/wattdepot/");
    RankTowers sample = new RankTowers();
    DailyEnergy sampleEnergy = new DailyEnergy();
    String testOutput;
    String line;
    String validOutput;
    // Constant double used to convert from watt to kilowatt.
    final double KILO = 1000.0;
    final String testStartDate = "2011-11-23";
    final String testEndDate = "2011-11-24";
    final String testOldDate = "2011-02-25";

    // Test with valid input
    assertNotSame("Testing getData with valid input",
        sample.getData(client, testStartDate, testEndDate).indexOf("\n"), -1);

    // Test validity of output values
    testOutput = sample.getData(client, testStartDate, testEndDate);

    // For each line
    do {
      line = testOutput.substring(0, testOutput.indexOf('\n'));
      testOutput = testOutput.substring(testOutput.indexOf('\n') + 1);
      validOutput =
          sampleEnergy.getData(client, line.substring(0, line.indexOf(' ')), testStartDate);

      assertTrue(
          "Testing getData for value correctness",
          Double.valueOf(line.substring(line.lastIndexOf(' '))) / KILO
              - Double.valueOf(validOutput) / KILO < Double.valueOf(validOutput) / KILO * 0.05);
    }
    while (testOutput.indexOf('\n') != -1);

    // Test with invalid client
    assertEquals("Testing getData with invalid client",
        sample.getData(new WattDepotClient("client/"), testStartDate, testEndDate),
        "Error: An error occurred while retrieving data.\n\n");

    // Test with invalid start date
    assertEquals("Testing getData with invalid start date",
        sample.getData(client, "yyyy-mm-dd", testEndDate),
        "Error: An error occurred while parsing the date.\n\n");

    // Test with invalid end date
    assertEquals("Testing getData with invalid end date",
        sample.getData(client, testStartDate, "yyyy-mm-dd"),
        "Error: An error occurred while parsing the date.\n\n");

    // Test with invalid date formatting
    assertEquals("Testing getData with invalid formatting",
        sample.getData(client, "alpha", "beta"),
        "Error: An error occurred while parsing the date; " + "the formatting is incorrect.\n\n");

    // Test with date that is out of bounds
    assertEquals("Testing getData with out-of-bounds date",
        sample.getData(client, "2011-16-32", "2011-34-64"),
        "Error: An error occurred in using the XMLGregorianCalendar class.\n\n");

    // Test with start date that is before server reset
    assertEquals("Testing getData with old start date", 
                  sample.getData(client, testOldDate, testEndDate),
                  "Error: An error occurred in the XML from the server.\n\n");
    
    // Test with end date that is before server reset
    assertEquals("Testing getData with old end date",
                  sample.getData(client, testEndDate, testOldDate),
                  "Error: An error occurred in the XML from the server.\n\n");
    
    // Test with end date earlier than start date
    assertEquals("Testing getData with incorrectly ordered dates", 
                  sample.getData(client, testEndDate, testStartDate),
                  "Error: An error occurred in the XML from the server.\n\n");
  }
}